#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    m_client=new QModbusTcpClient(this);
    connect(m_client,&QModbusTcpClient::stateChanged,this,&MainWindow::state_change_slot);

    ui->groupBox_2->setEnabled(false);

    ui->textEdit->setText("192.168.3.5");
    ui->textEdit_2->setText("5020");
}

MainWindow::~MainWindow()
{
    if(m_isConnect){
        m_client->disconnectDevice();
    }

    delete ui;
}

void MainWindow::state_change_slot(QModbusDevice::State state)
{
    qDebug()<<"state_change_slot";
    //emit modbus_state_change_signal(state);
}

void MainWindow::on_pushButton_clicked()
{
    connectModbusDevice();
}


void MainWindow::on_pushButton_2_clicked()
{
    redxianquanData();
}


void MainWindow::on_pushButton_3_clicked()
{
    redlisaninputData();
}


void MainWindow::on_pushButton_4_clicked()
{
    redinputjicunqiData();
}


void MainWindow::on_pushButton_5_clicked()
{
    redsavejicunqiData();
}

void MainWindow::connectModbusDevice()
{
    if(!m_isConnect){
        QString strHost = ui->textEdit->document()->toPlainText();
        QString strPort = ui->textEdit_2->document()->toPlainText();

        m_client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,strHost);
        m_client->setConnectionParameter(QModbusDevice::NetworkPortParameter,strPort);

        m_client->setTimeout(1000);
        m_client->setNumberOfRetries(3);

        if (!m_client->connectDevice()) {
            qDebug()<< "连接modbus设备失败";
            return;
        }

        qDebug()<< "成功连接到modbs设备";
        ui->pushButton->setText(tr("断开"));
        m_isConnect = true;
        ui->groupBox_2->setEnabled(true);
    }else{

        m_client->disconnectDevice();

        qDebug()<< "断开连接modbs设备";

        ui->pushButton->setText(tr("连接"));
        m_isConnect = false;
        ui->groupBox_2->setEnabled(false);

        ui->label_3->setText("");

        ui->textEdit_3->setText("");
        ui->textEdit_4->setText("");
        ui->textEdit_5->setText("");
        ui->textEdit_6->setText("");
        ui->textEdit_7->setText("");
        ui->textEdit_8->setText("");
        ui->textEdit_9->setText("");
        ui->textEdit_10->setText("");
        ui->textEdit_11->setText("");
        ui->textEdit_12->setText("");
    }
}

void MainWindow::onReadReady()
{
    auto reply = qobject_cast<QModbusReply*>(sender());
    if (nullptr == reply)
    {
        return;
    }

    ui->textEdit_3->setText("");
    ui->textEdit_4->setText("");
    ui->textEdit_5->setText("");
    ui->textEdit_6->setText("");
    ui->textEdit_7->setText("");
    ui->textEdit_8->setText("");
    ui->textEdit_9->setText("");
    ui->textEdit_10->setText("");
    ui->textEdit_11->setText("");
    ui->textEdit_12->setText("");


    //判断是否出错
    if (reply->error() == QModbusDevice::NoError)
    {
        //读取响应数据
        const QModbusDataUnit responseData = reply->result();

        qDebug() << "读到数据为：" << responseData.values();

        QVector<quint16> vectorData = responseData.values();

        ui->textEdit_3->setText(QString::number(vectorData[0]));
        ui->textEdit_4->setText(QString::number(vectorData[1]));
        ui->textEdit_5->setText(QString::number(vectorData[2]));
        ui->textEdit_6->setText(QString::number(vectorData[3]));
        ui->textEdit_7->setText(QString::number(vectorData[4]));
        ui->textEdit_8->setText(QString::number(vectorData[5]));
        ui->textEdit_9->setText(QString::number(vectorData[6]));
        ui->textEdit_10->setText(QString::number(vectorData[7]));
        ui->textEdit_11->setText(QString::number(vectorData[8]));
        ui->textEdit_12->setText(QString::number(vectorData[9]));

        ui->label_3->setText(tr("请求数据成功......"));

    }
    else if (reply->error() == QModbusDevice::ProtocolError)
    {
        ui->label_3->setText(tr("请求数据失败......"));
        qDebug() << "Read response Protocol error: " << reply->errorString();
    }
    else
    {
        ui->label_3->setText(tr("请求数据失败......"));
        qDebug() << "Read response Error: " << reply->errorString();
    }


    //删除reply
    reply->deleteLater();
}

void MainWindow::redxianquanData()
{
    QModbusDataUnit data(QModbusDataUnit::Coils, 0, 10);

    auto reply = m_client->sendReadRequest(data, 0x1);
    if (nullptr == reply)
    {
        qDebug() << "发送请求数据失败: " << m_client->errorString();
    }
    else
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &MainWindow::onReadReady);
        }
        else
        {
            //broadcast replies return immediately
            delete reply;
        }
    }
}

void MainWindow::redlisaninputData()
{
    QModbusDataUnit data(QModbusDataUnit::DiscreteInputs, 0, 10);

    auto reply = m_client->sendReadRequest(data, 0x1);
    if (nullptr == reply)
    {
        qDebug() << "发送请求数据失败: " << m_client->errorString();
    }
    else
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &MainWindow::onReadReady);
        }
        else
        {
            //broadcast replies return immediately
            delete reply;
        }
    }
}

void MainWindow::redinputjicunqiData()
{
    QModbusDataUnit data(QModbusDataUnit::InputRegisters, 0, 10);

    auto reply = m_client->sendReadRequest(data, 0x1);
    if (nullptr == reply)
    {
        qDebug() << "发送请求数据失败: " << m_client->errorString();
    }
    else
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &MainWindow::onReadReady);
        }
        else
        {
            //broadcast replies return immediately
            delete reply;
        }
    }
}

void MainWindow::redsavejicunqiData()
{
    QModbusDataUnit data(QModbusDataUnit::HoldingRegisters, 0, 10);

    auto reply = m_client->sendReadRequest(data, 0x1);
    if (nullptr == reply)
    {
        qDebug() << "发送请求数据失败: " << m_client->errorString();
    }
    else
    {
        if (!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, &MainWindow::onReadReady);
        }
        else
        {
            //broadcast replies return immediately
            delete reply;
        }
    }
}

//写线圈
void MainWindow::on_pushButton_7_clicked()
{
    //从地址0开始写10个线圈的值
    QModbusDataUnit writeData(QModbusDataUnit::Coils, 0, 10);
    for (int i = 0; i < writeData.valueCount(); i++)
    {
        writeData.setValue(i, i);
    }

    qDebug() << "发送的数据为： " << writeData.values();

    QModbusReply* reply = m_client->sendWriteRequest(writeData, 1);
    if (reply)
    {
        if (!reply->isFinished())
        {
            //接收响应信息
            connect(reply, &QModbusReply::finished, this, [this, reply](){
                if (reply->error() == QModbusDevice::ProtocolError)
                {
                    //接收到的响应信息是协议错误
                    qDebug() << "写入数据错误：" << reply->errorString();
                }
                else if (reply->error() != QModbusDevice::NoError)
                {
                    //接收到的响应消息是其它错误
                    qDebug() << "写入数据错误： " << reply->errorString();
                }
                else
                {
                    //接收到的消息没有错误 一般没有必要解析响应消息
                    const QModbusDataUnit data = reply->result();

                    qDebug() << "消息数据个数：" << data.valueCount() << " :" << data.values();

                }

                reply->deleteLater();
            });
        }
        else
        {
            //发送没有响应数据
            //broadcast replies return immediately
            reply->deleteLater();
        }
    }
    else
    {
        qDebug() << "sendWriteRequest Error: " << reply->errorString();
    }
}

//写保持寄存器
void MainWindow::on_pushButton_6_clicked()
{
    //从地址0开始写10个线圈的值
    QModbusDataUnit writeData(QModbusDataUnit::HoldingRegisters, 0, 10);
    for (int i = 0; i < writeData.valueCount(); i++)
    {
        writeData.setValue(i, i);
    }

    qDebug() << "发送的数据为： " << writeData.values();

    QModbusReply* reply = m_client->sendWriteRequest(writeData, 1);
    if (reply)
    {
        if (!reply->isFinished())
        {
            //接收响应信息
            connect(reply, &QModbusReply::finished, this, [this, reply](){
                if (reply->error() == QModbusDevice::ProtocolError)
                {
                    //接收到的响应信息是协议错误
                    qDebug() << "写入数据错误：" << reply->errorString();
                }
                else if (reply->error() != QModbusDevice::NoError)
                {
                    //接收到的响应消息是其它错误
                    qDebug() << "写入数据错误： " << reply->errorString();
                }
                else
                {
                    //接收到的消息没有错误 一般没有必要解析响应消息
                    const QModbusDataUnit data = reply->result();

                    qDebug() << "消息数据个数：" << data.valueCount() << " :" << data.values();

                }

                reply->deleteLater();
            });
        }
        else
        {
            //发送没有响应数据
            //broadcast replies return immediately
            reply->deleteLater();
        }
    }
    else
    {
        qDebug() << "sendWriteRequest Error: " << reply->errorString();
    }
}

